package com.wbihua.common.metrics.metric.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.SafeConcurrentHashMap;
import com.wbihua.common.metrics.manager.MetricManager;
import com.wbihua.common.metrics.metric.EventMeterSummary;
import com.wbihua.common.metrics.type.EventSummaryType;
import io.micrometer.core.instrument.DistributionSummary;

import java.util.List;

public class EventSummary implements EventMeterSummary {
    private static final SafeConcurrentHashMap<List<String>, DistributionSummary> POOL = new SafeConcurrentHashMap<>();
    private DistributionSummary summary;

    private final EventSummaryType counterType;
    private MetricManager metricManager;

    public EventSummary(EventSummaryType counterType) {
        this.counterType = counterType;
    }
    public EventSummary(EventSummaryType counterType, MetricManager metricManager) {
        this(counterType);
        this.metricManager = metricManager;
    }
    @Override
    public void registry(MetricManager metricManager) {
        /*
        summary = DistributionSummary.builder(this.counterType.getName())
                .tags(metricManager.getTags())
                .description(this.counterType.getDescription())
                .baseUnit(this.counterType.getBaseUnit())
                .register(metricManager.getMetricRegistry());*/

    }

    @Override
    public <T> T getMeter() {
        return (T)this.summary;
    }

    @Override
    public <T> T getMeter(String... tagValues) {
        return (T)POOL.get(tagValues);
    }

    @Override
    public EventSummaryType getCounterType() {
        return this.counterType;
    }

    @Override
    public void record(double amount) {
        summary.record(amount);
    }

    @Override
    public void record(double amount, String... tagValues) {
        getSummary(tagValues).record(amount);
    }

    private DistributionSummary getSummary(String[] tagValues) {
        if (tagValues.length != counterType.getTags().length) {
            throw new IllegalArgumentException("Incorrect number of labels.");
        }
        for (String value: tagValues) {
            if (value == null) {
                throw new IllegalArgumentException("Label cannot be null.");
            }
        }
        return POOL.computeIfAbsent(ListUtil.toList(tagValues), values -> {
            DistributionSummary.Builder builder = DistributionSummary.builder(this.counterType.getName())
                    .tags(metricManager.getTags());
            String[] tags = counterType.getTags();
            for (int i = 0; i < values.size(); i++) {
                builder.tag(tags[i], values.get(i));
            }
            return builder.publishPercentiles(this.counterType.getPercentiles())
                    .publishPercentileHistogram(true)
                    .description(counterType.getDescription())
                    .baseUnit(counterType.getBaseUnit())
                    .register(metricManager.getMetricRegistry());
        });
    }
}
